
#include "debug.h"
#include "cmd_local.h"

using namespace std ;

bool handle4gConfigMod(char *str[], int sockfd) 
{
	bool ret = true ;

	//DEBUG(LOG_DEBUG, "macaddr: %s", str[2]);

	if(str[2] == NULL)
	{
		LOG(LOG_ERR, "4g config modify error, the mode is null");
		return false ;
	}

	int mode = atoi(str[2]) ;
	
	ret = updateG4InfoIntoDB(0, mode, str[3], str[4], str[5]);

	return ret ;
}

bool handle4gConfigQue(char *str[], int sockfd)
{
	bool ret = true ;
	
	ostringstream retValue ;
	string retValueStr ;

	//retValue << str[0] << "|" << str[1] ;

	ret = getG4InfoFromDB() ;
	if(ret)
	{
		DEBUG(LOG_DEBUG, "4g config Query startMode : %d", g4.startMode);
		retValue << g4.startMode ;

		DEBUG(LOG_DEBUG, "4g config Query apn4g : %s", g4.apn4g.c_str());
		retValue << "|" << g4.apn4g ;

		DEBUG(LOG_DEBUG, "4g config Query username : %s", g4.username.c_str());
		retValue << "|" << g4.username;

		DEBUG(LOG_DEBUG, "4g config Query passwd : %s", g4.passwd.c_str());
		retValue << "|" << g4.passwd;
	}
	else
	{
		LOG(LOG_ERR, "Vpn config Query error");
		retValue << 0 ;
	}

	retValueStr = retValue.str() ;

	send(sockfd, retValueStr.c_str(), strlen(retValueStr.c_str()), 0) ;

 	return ret;
}


bool handle4gConfig (char *str[], int sockfd)
{
	bool ret = true ;

	int action = atoi(str[1]) ;

	switch(action)
	{
		case MOD:
			LOG(LOG_INFO, "4g config action: %s", "MOD");
			ret = handle4gConfigMod(str, sockfd);
			break;
		case QUE:
			LOG(LOG_INFO, "4g config action: %s", "QUERY");
			ret = handle4gConfigQue(str, sockfd);
			break;
		
		default :
			break ;
	}
	
	return ret ;

}


bool handleVpnConfigMod(char *str[], int sockfd) 
{
	bool ret = true ;

	//DEBUG(LOG_DEBUG, "macaddr: %s", str[2]);

	if((str[3] != NULL) && (atoi(str[2]) != 1))
	{
		if(!check_ip(str[3]))
		{
			LOG(LOG_ERR, "ip address invalid.") ;
			return false ;
		}
	}

	for (int i=2 ;i <=5; i++)
	{
		if (i != 3)
		{
			LOG(LOG_DEBUG, "str[%d] = %d", i, atoi(str[i])) ;
			
			if((atoi(str[i]) != 0) && (atoi(str[i]) != 1) )
			{
				LOG(LOG_ERR, "The %d parameter is invalid", i);
				return false ;
			}
			
		}
	}

	int server_or_not = atoi(str[2]) ;
	int proto = atoi(str[4]) ;
	int mode = atoi(str[5]) ;

	if(server_or_not != 1)
		ret = updateVpnServerIpIntoDB(server_or_not, str[3], proto, mode);
	else
		ret = updateVpnServerIpIntoDB(server_or_not, "", proto, mode);
	
	return ret ;
}

bool handleVpnConfigQue(char *str[], int sockfd)
{
	bool ret = true ;
	
	ostringstream retValue ;
	string retValueStr ;
	string vpnServerIP ;

	//retValue << str[0] << "|" << str[1] ;

	ret = getVpnServerIpFromDB() ;
	if(ret)
	{
		DEBUG(LOG_DEBUG, "Vpn config Query serverOrNot : %d", vpnServer.serverOrNot);
		retValue << vpnServer.serverOrNot ;

		DEBUG(LOG_DEBUG, "Vpn config Query vpnServerIp : %s", vpnServer.vpnServerIp.c_str());
		if(vpnServer.vpnServerIp == "")
			vpnServerIP = "NULL" ;
		else
			vpnServerIP = vpnServer.vpnServerIp ;
		retValue << "|" <<  vpnServerIP;

		DEBUG(LOG_DEBUG, "Vpn config Query proto : %d", vpnServer.proto);
		retValue << "|" << vpnServer.proto ;

		DEBUG(LOG_DEBUG, "Vpn config Query backUpMode : %d", vpnServer.backUpMode);
		retValue << "|" << vpnServer.backUpMode ;
	}
	else
	{
		LOG(LOG_ERR, "Vpn config Query error");
		retValue << 0 ;
	}

	retValueStr = retValue.str() ;

	send(sockfd, retValueStr.c_str(), strlen(retValueStr.c_str()), 0) ;

 	return ret;
}


bool handleVpnConfig (char *str[], int sockfd)
{
	bool ret = true ;

	int action = atoi(str[1]) ;

	switch(action)
	{
		case MOD:
			LOG(LOG_INFO, "vpn config action: %s", "MOD");
			ret = handleVpnConfigMod(str, sockfd);
			break;
		case QUE:
			LOG(LOG_INFO, "vpn config action: %s", "QUERY");
			ret = handleVpnConfigQue(str, sockfd);
			break;
		
		default :
			break ;
	}
	
	return ret ;

}


bool handVlanConfigCmdAdd(char *str[], int sockfd)
{
	bool ret = true ;

	for (int i=2 ; i<=4; i++)
	{
		if(str[i] == NULL)
		{
			LOG(LOG_ERR, "Dtr[%d] is null. Invalid parameter .", i);
			return false ;
		}
	}

	int vlanId = atoi(str[2]);
	int qinqOrNot = atoi(str[4]);

	if((vlanId < 1) || (vlanId > 4096))
	{
		LOG(LOG_ERR, "Vlan adding ,invalid vlan id ") ;
		return false ;
	}

	if( (qinqOrNot !=0) && (qinqOrNot != 1))
	{
		LOG(LOG_ERR, "qinqOrNot parameter invalid ") ;
		return false ;
	}

	ret = insertProtectedVlanFromS4pInDB(vlanId, str[3],qinqOrNot) ;

	if(ret)
	{
		ostringstream outStr ;
		string vlanName ;
	
		add_vlan(str[3], vlanId) ;
		add_bridge(vlanId);

		outStr << str[3] << "." << vlanId ;
		vlanName = outStr.str();

		cout << vlanName ;
		
		add_inface_to_bridge(vlanId, vlanName.c_str()) ;
	}

	return ret ;
}

bool handVlanConfigCmdDel(char *str[], int sockfd)
{
	bool ret = true ;

	if(str[2] == NULL)
	{
		LOG(LOG_ERR, "Vlan deleting , invalid vlan id .") ;
		return false ;
	}

	int vlanId = atoi(str[2]);
	if((vlanId < 1) || (vlanId > 4096))
	{
		LOG(LOG_ERR, "Vlan deleting , invalid vlan id ") ;
		return false ;
	}

	delProtectVlanFromS4pInDB(vlanId) ;

	ostringstream outStr ;
	string delCmd ;

	outStr << "vconfig rem " << str[3] << "." << vlanId ;
	delCmd = outStr.str();

	cout << "del cmd " << delCmd ;

	system(delCmd.c_str()) ;

	return ret ;
}


bool handVlanConfigCmdQue(char *str[], int sockfd)
{
	int ret = true ;
	int firstFlag = 0 ;
	vector<VlanProtected>::iterator vidFs4p;

	ostringstream retValue ;
	string retValueStr ;

	vidFs4p = VlanProtectedVector.begin() ;

	//retValue << str[0] << "|" << str[1] ;

	if(VlanProtectedVector.empty())
	{
		//cout << "port from vlan vector empty." << endl ;
		DEBUG(LOG_DEBUG, "VLAN empty") ;
		
	}
	else 
	{
		for (vidFs4p = VlanProtectedVector.begin(); vidFs4p != VlanProtectedVector.end(); vidFs4p++)
		{
			if(retValueStr.size() > 4080)
			{
				//retValue << "----" ;
				//retValueStr = retValue.str() ; 
				send(sockfd, retValueStr.c_str(), strlen(retValueStr.c_str()), 0) ;
				retValue.str("") ;
			}

			if(firstFlag == 0)
				firstFlag = 1 ;
			else
				retValue << ":" ;
				
		
			retValue << (*vidFs4p).vlanId 
					 << "|" << (*vidFs4p).inface
					 << "|" << (*vidFs4p).qinqOrNot ;

			retValueStr = retValue.str() ;
		}
	}

	retValue << ":end" ;

	retValueStr = retValue.str() ;
	DEBUG(LOG_DEBUG, "reture value : %s", retValueStr.c_str()) ;
	send(sockfd, retValueStr.c_str(), strlen(retValueStr.c_str()), 0) ;
	
	return ret ;
}

bool handVlanConfigCmd(char *str[], int sockfd)
{
	int ret = true ;

	int action = atoi(str[1]) ;

	switch(action)
	{
		case ADD:
			LOG(LOG_INFO, "Vlan config action: %s", "ADD");
			ret = handVlanConfigCmdAdd(str, sockfd);
			break;
		case DEL:
			LOG(LOG_INFO, "Vlan config action: %s", "DEL");
			ret = handVlanConfigCmdDel(str, sockfd) ;
			break;
		case QUE:
			LOG(LOG_INFO, "Vlan config action: %s", "QUERY");
			ret = handVlanConfigCmdQue(str, sockfd);
			break;
		
		default :
			break ;
	}

	return ret ;
}

bool handProtectVlanConfigCmdAdd(char *str[], int sockfd)
{
	bool ret = true ;

	for (int i=2 ; i<=4; i++)
	{
		if(str[i] == NULL)
		{
			LOG(LOG_ERR, "Dtr[%d] is null. Invalid parameter .", i);
			return false ;
		}
	}

	int vlanId = atoi(str[2]);
	int qinqOrNot = atoi(str[4]);

	if((vlanId < 1) || (vlanId > 4096))
	{
		LOG(LOG_ERR, "Vlan adding ,invalid vlan id ") ;
		return false ;
	}

	if( (qinqOrNot !=0) && (qinqOrNot != 1))
	{
		LOG(LOG_ERR, "qinqOrNot parameter invalid ") ;
		return false ;
	}

	ret = insertProtectedVlanFromS4pInDB(vlanId, str[3],qinqOrNot) ;
	getProtectedVlanFromS4pInDB();
	return ret ;
}

bool handProtectVlanConfigCmdDel(char *str[], int sockfd)
{
	bool ret = true ;

	if(str[2] == NULL)
	{
		LOG(LOG_ERR, "Vlan deleting , invalid vlan id .") ;
		return false ;
	}

	int vlanId = atoi(str[2]);
	if((vlanId < 1) || (vlanId > 4096))
	{
		LOG(LOG_ERR, "Vlan deleting , invalid vlan id ") ;
		return false ;
	}

	ret = delProtectVlanFromS4pInDB(vlanId) ;
	getProtectedVlanFromS4pInDB() ;

	return ret ;
}


bool handProtectVlanConfigCmdQue(char *str[], int sockfd)
{
	bool ret = true ;
	int firstFlag = 0 ;
	vector<VlanProtected>::iterator vidFs4p;

	ostringstream retValue ;
	string retValueStr ;

	vidFs4p = VlanProtectedVector.begin() ;

	//retValue << str[0] << "|" << str[1] ;

	cout << "vlan protect vector size " << VlanProtectedVector.size() << endl ;

	if(VlanProtectedVector.empty())
	{
		//cout << "port from vlan vector empty." << endl ;
		DEBUG(LOG_DEBUG, "VLAN empty") ;
		
	}
	else 
	{
		for (vidFs4p = VlanProtectedVector.begin(); vidFs4p != VlanProtectedVector.end(); vidFs4p++)
		{
			if(retValueStr.size() > 4080)
			{
				send(sockfd, retValueStr.c_str(), strlen(retValueStr.c_str()), 0) ;
				retValue.str("") ;
			}

			if(firstFlag == 0)
				firstFlag = 1 ;
			else
				retValue << ":" ;
				
		
			retValue << (*vidFs4p).vlanId 
					 << "|" << (*vidFs4p).inface
					 << "|" << (*vidFs4p).qinqOrNot ;

			retValueStr = retValue.str() ;

			
		}
	}

	retValue << ":end" ;
	
	retValueStr = retValue.str() ;
	DEBUG(LOG_DEBUG, "reture value : %s", retValueStr.c_str()) ;
	send(sockfd, retValueStr.c_str(), strlen(retValueStr.c_str()), 0) ;
	
	return ret ;
}

bool handProtectVlanConfigCmd(char *str[], int sockfd)
{
	int ret = true ;

	int action = atoi(str[1]) ;

	switch(action)
	{
		case ADD:
			LOG(LOG_INFO, "Vlan Protect config action: %s", "ADD");
			ret = handProtectVlanConfigCmdAdd(str, sockfd);
			break;
		case DEL:
			LOG(LOG_INFO, "Vlan Protect config action: %s", "DEL");
			ret = handProtectVlanConfigCmdDel(str, sockfd) ;
			break;
		case QUE:
			LOG(LOG_INFO, "Vlan Protect config action: %s", "QUERY");
			ret = handProtectVlanConfigCmdQue(str, sockfd);
			break;
		
		default :
			break ;
	}

	return ret ;
}


bool handlePeerMacConfigMod(char *str[], int sockfd) 
{
	bool ret = true ;

	DEBUG(LOG_DEBUG, "macaddr: %s", str[2]);

	if(str[2] == NULL)
	{
		LOG(LOG_ERR, "Mac address is null .Return false ") ;
		return false ;
	}
	if(!mac_verify(Trim(str[2]))) {
		LOG(LOG_ERR, "Mac address format error, please input a right address \n");
		return false ;
	}

	ret = updatePeerMac( str[2]) ;

	return ret ;
}

bool handlePeerMacConfigQue(char *str[], int sockfd)
{
	bool ret = true ;

	ostringstream retValue ;
	string retValueStr ;

	//retValue << str[0] << "|" << str[1] ;

	ret = getPeerMac() ;
	if(ret)
	{
		DEBUG(LOG_DEBUG, "PeerMac Query : %s", peerMacAddr.c_str());
		retValue << peerMacAddr ;
		
	}
	else
	{
		LOG(LOG_ERR, "Get peer mac error");
		retValue << 0 ;
	}

	retValueStr = retValue.str() ;

	send(sockfd, retValueStr.c_str(), strlen(retValueStr.c_str()), 0) ;
 	return ret;
}

bool handlePeerMacConfig (char *str[], int sockfd)
{
	bool ret = true ;

	int action = atoi(str[1]) ;

	switch(action)
	{
		case MOD:
			LOG(LOG_INFO, "peer mac config action: %s", "MOD");
			ret = handlePeerMacConfigMod(str, sockfd);
			break;
		case QUE:
			LOG(LOG_INFO, "peer mac config action: %s", "QUERY");
			ret = handlePeerMacConfigQue(str, sockfd);
			break;
		
		default :
			break ;
	}
	
	return ret ;

}

bool dealCmdLocal(char buf[], int conn) 
{
	int i = 0 ;
	int j = 0 ;
	char *tok ;
	bool ret = true ;
	char *parse[15]  = {NULL};

	tok = strtok(buf, "|");
	while(tok != NULL)
	{
		parse[i] = tok ;
		DEBUG(LOG_DEBUG,"parse[%d] : %s\n",i, parse[i]);
		i++ ;
		tok = strtok(NULL, "|") ;
	}
	
	switch (atoi(parse[0])) 
	{
		case PPP4G_CONFIG_CMD:
			LOG(LOG_INFO, "handle PPP4G_CONFIG_CMD");
			ret = handle4gConfig(parse, conn) ;
			break ;
		case VPN_CONFIG_CMD :
			LOG(LOG_INFO, "handle VPN_CONFIG_CMD");
			ret = handleVpnConfig(parse, conn) ;
			break ;
		case VLAN_CONFIG_CMD:
			LOG(LOG_INFO, "handle VLAN_CONFIG_CMD");
			ret = handVlanConfigCmd(parse, conn) ;
			break ;
		case VLAN_PRO_CONFIG_CMD :
			LOG(LOG_INFO, "handle VLAN_PRO_CONFIG_CMD");
			ret = handProtectVlanConfigCmd(parse, conn) ;
			break ;
		case PEER_MAC_CONFIG_CMD:
			LOG(LOG_INFO, "handle PEER_MAC_CONFIG_CMD");
			ret = handlePeerMacConfig(parse, conn) ;
			break ;

		default :
			break ;
	}

	if(atoi(parse[1]) != QUE)
	{
		
		ostringstream retValue ;
		string retValueStr ;
	
		retValue << ret ;
	
		retValueStr = retValue.str();
	
		send(conn, retValueStr.c_str(), strlen(retValueStr.c_str()), 0) ;
	}

	for (j = 0; j < 15 ;j ++)
	{
		parse[i] = NULL ;
	}

	return ret ;
}



